package com.spedencencies.springjdbc2.utils;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;

/**
 * @author zhizhou   2024/10/9 14:17
 */
public class DateUtils {
    // 默认时间格式
    private static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    private static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
    
    // 格式化器
    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT);
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT);
    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT);
    
    // 获取当前时间
    public static LocalDateTime getCurrentDateTime() {
        return LocalDateTime.now();
    }
    
    public static LocalDate getCurrentDate() {
        return LocalDate.now();
    }
    
    public static LocalTime getCurrentTime() {
        return LocalTime.now();
    }
    
    // 日期转字符串
    public static String formatDateTime(LocalDateTime dateTime) {
        return dateTime.format(DATE_TIME_FORMATTER);
    }
    
    public static String formatDateTime(Date date) {
        return formatDateTime(toLocalDateTime(date));
    }
    
    public static String formatDate(LocalDate date) {
        return date.format(DATE_FORMATTER);
    }
    
    public static String formatDate(Date date) {
        return formatDate(toLocalDate(date));
    }
    
    public static String formatTime(LocalTime time) {
        return time.format(TIME_FORMATTER);
    }
    
    public static String formatTime(Date date) {
        return formatTime(toLocalDateTime(date).toLocalTime());
    }
    
    // 字符串转日期
    public static LocalDateTime parseDateTime(String dateTimeStr) {
        return LocalDateTime.parse(dateTimeStr, DATE_TIME_FORMATTER);
    }
    
    public static LocalDate parseDate(String dateStr) {
        return LocalDate.parse(dateStr, DATE_FORMATTER);
    }
    
    public static LocalTime parseTime(String timeStr) {
        return LocalTime.parse(timeStr, TIME_FORMATTER);
    }
    
    // 日期加减操作
    public static LocalDateTime addDays(LocalDateTime dateTime, long days) {
        return dateTime.plusDays(days);
    }
    
    public static LocalDateTime addDays(Date date, long days) {
        return addDays(toLocalDateTime(date), days);
    }
    
    public static LocalDateTime addHours(LocalDateTime dateTime, long hours) {
        return dateTime.plusHours(hours);
    }
    
    public static LocalDateTime addHours(Date date, long hours) {
        return addHours(toLocalDateTime(date), hours);
    }
    
    public static LocalDateTime addMinutes(LocalDateTime dateTime, long minutes) {
        return dateTime.plusMinutes(minutes);
    }
    
    public static LocalDateTime addMinutes(Date date, long minutes) {
        return addMinutes(toLocalDateTime(date), minutes);
    }
    
    public static LocalDateTime addSeconds(LocalDateTime dateTime, long seconds) {
        return dateTime.plusSeconds(seconds);
    }
    
    public static LocalDateTime addSeconds(Date date, long seconds) {
        return addSeconds(toLocalDateTime(date), seconds);
    }
    
    // 时间区间计算
    public static long betweenDates(LocalDate startDate, LocalDate endDate) {
        return ChronoUnit.DAYS.between(startDate, endDate);
    }
    
    public static long betweenDates(Date startDate, Date endDate) {
        return betweenDates(toLocalDate(startDate), toLocalDate(endDate));
    }
    
    public static long betweenDateTimes(LocalDateTime startDateTime, LocalDateTime endDateTime) {
        return ChronoUnit.SECONDS.between(startDateTime, endDateTime);
    }
    
    public static long betweenDateTimes(Date startDateTime, Date endDateTime) {
        return betweenDateTimes(toLocalDateTime(startDateTime), toLocalDateTime(endDateTime));
    }
    
    // 转换成旧的 Date 类
    public static Date toDate(LocalDateTime dateTime) {
        ZoneId zone = ZoneId.systemDefault();
        ZonedDateTime zdt = dateTime.atZone(zone);
        return Date.from(zdt.toInstant());
    }
    
    public static Date toDate(LocalDate date) {
        return Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }
    
    // 将 Date 转 LocalDateTime
    public static LocalDateTime toLocalDateTime(Date date) {
        Instant instant = date.toInstant();
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }
    
    // 将 Date 转 LocalDate
    public static LocalDate toLocalDate(Date date) {
        return toLocalDateTime(date).toLocalDate();
    }
    
    // 将字符串或 Date 转 LocalDateTime
    public static LocalDateTime toLocalDateTime(String dateTimeStr) {
        return parseDateTime(dateTimeStr);
    }
    
    public static LocalDateTime toLocalDateTime(Object dateOrString) {
        if (dateOrString instanceof Date) {
            return toLocalDateTime((Date) dateOrString);
        } else if (dateOrString instanceof String) {
            return parseDateTime((String) dateOrString);
        } else {
            throw new IllegalArgumentException("Unsupported type. Must be Date or String.");
        }
    }
    
    // 获取当前时间戳
    public static long getCurrentTimestamp() {
        return Instant.now().getEpochSecond();
    }
    
    // 时间戳转换为 LocalDateTime
    public static LocalDateTime timestampToLocalDateTime(long timestamp) {
        return LocalDateTime.ofEpochSecond(timestamp, 0, ZoneOffset.UTC);
    }
    
    // LocalDateTime 转时间戳
    public static long toTimestamp(LocalDateTime dateTime) {
        return dateTime.toEpochSecond(ZoneOffset.UTC);
    }
}
